﻿using Newtonsoft.Json;
using Spire.Pdf;
using Spire.Pdf.HtmlConverter;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Xps.Packaging;

namespace WpfTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //this.Maximized();
            BindTreeView();
            Trace.Listeners.Add(new TextWriterTraceListener(DateTime.Now.ToString("yyyyMMdd") + ".log"));
            Trace.WriteLine("test log");
        }

        public void Maximized()
        {
            this.Left = 0;//设置位置
            this.Top = 0;
            Rect rc = SystemParameters.WorkArea;//获取工作区大小
            this.Width = rc.Width;
            this.Height = rc.Height;
        }

        private void BindTreeView()
        {
            Trace.WriteLine("html2Pdf");
            TreeNode node1 = new TreeNode("1", "");
            TreeNode node2 = new TreeNode("2", "");
            TreeNode node1_1 = new TreeNode("1.1", "");
            TreeNode node1_2 = new TreeNode("1.2", "");
            TreeNode node1_3 = new TreeNode("1.3", "");
            TreeNode node1_2_1 = new TreeNode("1.2.1", "");
            TreeNode node1_2_2 = new TreeNode("1.2.2", "");
            node1_2.Children = new List<TreeNode>() { node1_2_1, node1_2_2 };
            node1.Children = new List<TreeNode>() { node1_1, node1_2, node1_3 };
            TreeNode node3 = new TreeNode("3", "");
            var list = new List<TreeNode>();
            string content = "";
            for (int i = 0; i < 100; i++)
            {
                list.Add(new TreeNode("3." + i, ""));
                content += "文章水水水水";
            }
            list.Add(new TreeNode("3.101" + content, ""));
            node3.Children = list;
            List<TreeNode> nodes = new List<TreeNode>() { node1, node2, node3 };
            this.MyTree.ItemsSource = nodes;
        }

        private void html2Pdf(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("html2Pdf");
            string inputFile = "..\\..\\test\\html2pdf\\test.html";
            string outputFile = "..\\..\\test\\html2pdf\\output.pdf";
            PdfDocument pdf = new PdfDocument();
            PdfHtmlLayoutFormat htmlLayoutFormat = new PdfHtmlLayoutFormat();
            htmlLayoutFormat.IsWaiting = false;
            PdfPageSettings setting = new PdfPageSettings();
            setting.Size = PdfPageSize.A4;
            string htmlCode = File.ReadAllText(inputFile);
            //use single thread to generate the pdf from above html code
            Thread thread = new Thread(() =>
            { pdf.LoadFromHTML(htmlCode, false, setting, htmlLayoutFormat); });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
            thread.Join();
            pdf.SaveToFile(outputFile);
            System.Diagnostics.Process.Start(outputFile);
        }

        private void svg2Pdf(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("svg2Pdf");
            string inputFile = "..\\..\\test\\svg2pdf\\test.svg";
            string outputFile = "..\\..\\test\\svg2pdf\\output.pdf";
            PdfDocument pdf = new PdfDocument();
            pdf.LoadFromSvg(inputFile);
            pdf.SaveToFile(outputFile);
            System.Diagnostics.Process.Start(outputFile);
        }

        private void pdf2Xps(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("pdf2Xps");
            string inputFile = "..\\..\\test\\svg2pdf\\output.pdf";
            string outputFile = "..\\..\\test\\svg2pdf\\output.xps";
            PdfDocument pdf = new PdfDocument();
            pdf.LoadFromFile(inputFile);
            pdf.SaveToFile(outputFile, FileFormat.XPS);
            System.Diagnostics.Process.Start(outputFile);
        } 
        
        private void loadDoc(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("loadDoc");
            string outputFile = "..\\..\\test\\svg2pdf\\output.xps";
            XpsDocument doc = new XpsDocument(outputFile, System.IO.FileAccess.Read);
            documentViewer.Document = doc.GetFixedDocumentSequence();
        }

        private void print(object sender, RoutedEventArgs e)
        {
            Trace.WriteLine("print");
            documentViewer.Print();
        }

        private void textWidth(object sender, RoutedEventArgs e)
        {
            string inputFile = "aあｑＱQW中文日本かい下記っさ33";

            var t = MyFont.GetFontWidthHeight(inputFile, this, 10, "MS UI Gothic");
            Trace.WriteLine("text width:" + t.width + ",height:" + t.height);
        }

        private void dataGroup(object sender, RoutedEventArgs e)
        {
            List<Dictionary<string, Object>> elements = new List<Dictionary<string, Object>>();
            //{ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
            for (int i = 0; i < 20; i++)
            {
                var item = new Dictionary<string, Object>();
                item.Add("id", i + 1);
                item.Add("relations", new List<Dictionary<string, Object>>());
                elements.Add(item);
            }
            List<List<int>> relations = new List<List<int>>();
            relations.Add(new List<int> { 1, 4 });
            relations.Add(new List<int> { 14, 7 });
            relations.Add(new List<int> { 13, 5 });
            relations.Add(new List<int> { 1, 5 });
            relations.Add(new List<int> { 8, 11 });
            relations.Add(new List<int> { 15, 8 });
            relations.Add(new List<int> { 19, 16 });
            relations.Add(new List<int> { 2, 6 });
            relations.Add(new List<int> { 3, 7 });
            relations.Add(new List<int> { 10, 7 });
            relations.Add(new List<int> { 4, 9 });
            relations.Add(new List<int> { 4, 13 });
            relations.Add(new List<int> { 16, 8 });
            relations.Add(new List<int> { 11, 17 });
            relations.Add(new List<int> { 12, 13 });
            // {1, 4, 5, 9, 12, 13}
            // {3, 7,10, 14}
            // {8, 11, 15, 16, 17, 19}
            // {2, 6}
            // {18}
            // {20}

            List<List<int>> groups = JsonConvert.DeserializeObject<List<List<int>>>(JsonConvert.SerializeObject(relations));
            foreach (var element in elements)
            {
                int id = (int)element["id"];
                int cnt = 0;
                foreach (var relation in relations)
                {
                    if (relation.Contains(id))
                    {
                        cnt += 1;
                    }
                }
                if (cnt == 0)
                {
                    groups.Add(new List<int> { id });
                }
            }

            var result = new List<List<int>>();
            for (int i = 0; i < elements.Count; i++)
            {
                if (i == 0)
                {
                    result = groupProcess(groups);
                    continue;
                }

                int cnt = 0;
                foreach (var group in result)
                {
                    cnt += group.Count;
                }
                if (cnt == elements.Count)
                {
                    break;
                }

                result = groupProcess(result);
            }

            Trace.WriteLine(JsonConvert.SerializeObject(result));
        }

        private List<List<int>> groupProcess(List<List<int>> groups)
        {
            List<List<int>> result = new List<List<int>>();

            var changeIndexList = new List<int>();
            for (int i = 0; i < groups.Count; i++)
            {
                if (changeIndexList.Contains(i))
                {
                    continue;
                }
                var group1 = groups[i];
                for (int k = 0; k < group1.Count; k++)
                {
                    var id = group1[k];
                    for (int j = i + 1; j < groups.Count; j++)
                    {
                        var group2 = groups[j];
                        if (group2.Contains(id))
                        {
                            foreach (var id2 in group2)
                            {
                                if (!group1.Contains(id2))
                                {
                                    group1.Add(id2);
                                }
                            }
                            changeIndexList.Add(j);
                            break;
                        }
                    }
                }
            }
            for (int i = 0; i < groups.Count; i++)
            {
                if (changeIndexList.Contains(i))
                {
                    continue;
                }
                result.Add(groups[i]);
            }
            return result;
        }


    }
}
